package com.onepiece.shipelves.common.utils;

import org.apache.commons.codec.digest.DigestUtils;

import java.util.Map;
import java.util.stream.Stream;

/**
 * 收集redis的key，不同数据结构的key切记不能重复
 *
 * @author guoyanjiang
 * @date 2018/4/19
 */
public class CacheUtil {

    public static final String KEY_PREFIX_VIEW_COUNT = "view_count_";
    public static final String IM_MESSAGE_ID = "im_message_id";
    public static final String SYS_MESSAGE_ID = "sys_message_id";
    public static final String IM_USER_UUID_LIST = "im_user_uuid_list";
    public static final String IM_USER_MESSAGE_LIST = "im_user_message_list";
    public static final String IM_USER_TOKEN_CHATSERVER_LIST = "im_user_token_chatserver_list";
    public static final String IM_USERINFO = "im_userinfo";
    public static final String TOP_COIN_LIST_MULTI_TICKERKEYS = "TopCoinList_MultiTickerkeys";
    public static final String TOP_COIN_LIST_COIN_PAIR_DAY_RECORDS = "TopCoinList_CoinPairDayRecords";
    public static final String TOP_COIN_LIST = "TopCoinList";

    /**
     * AU key格式：日期_产品名称_客户端类型_设备类型
     */
    public static final String DAU_FORMAT = "dau_%s_%s_%s_%s";
    public static final String MAU_FORMAT = "mau_%s_%s_%s_%s";
    private static final String HAU_FORMAT = "hau_%s_%s_%s";

    /**
     * UV key格式：日期_产品名称
     */
    public static final String DUV_FORMAT = "duv_%s_%s";
    public static final String MUV_FORMAT = "muv_%s_%s";
    private static final String HUV_FORMAT = "hau_%s";

    public static String getCacheKey(Map<String, Object> map) {
        StringBuilder builder = new StringBuilder();
        map.entrySet().forEach(entry -> {
            builder.append("&" + entry.getKey() + "=");
            builder.append(entry.getValue() != null ? entry.getValue() : "");
        });
        return changeHashIfNeed(builder.toString());
    }

    public static String getCacheKey(Object[] params) {
        StringBuilder builder = new StringBuilder();
        Stream.of(params)
                .filter(obj -> obj != null)
                .forEach(obj -> {
                    String feature = obj instanceof String ? obj.toString() : JsonUtil.toJson(obj);
                    builder.append(changeHashIfNeed(feature));
                });
        return builder.toString();
    }

    private static String changeHashIfNeed(String context) {
        if (isChinese(context) || context.length() > 100) {
            return DigestUtils.sha1Hex(context);
        }
        return context;
    }

    // 判断一个字符是否是中文
    private static boolean isChinese(char ch) {
        //获取此字符的UniCodeBlock
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(ch);
        //  GENERAL_PUNCTUATION 判断中文的“号
        //  CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号
        //  HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的，号
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }

    // 判断一个字符串是否含有中文
    public static boolean isChinese(String str) {
        if (str == null) {
            return false;
        }
        for (char c : str.toCharArray()) {
            if (isChinese(c)) {
                // 有一个中文字符就返回
                return true;
            }
        }
        return false;
    }

    public static String getActivityDrawTimeModelKey(Long uid, Long activityId) {
        return String.format("app_activity_%d_draw_time_model_%d", activityId, uid);
    }

    public static String getActivityInviteDrawKey(Long uid, Long activityId) {
        return String.format("app_activity_%d_invite_draw_time_%d", activityId, uid);
    }

    //指数需要保存redis，列表从数据库中获取放入内存缓存，列表从api获取的放入redis缓存，用来循环获取行情和权重，表现等数据
    //指数行情第一次获取n天数据保存入数据库，然后从数据库获取第一页数据放入redis

    public static String getIndexListKey() {
        return "index_coin_list";
    }

    public static String get8BTCIndexRebaseValueKey() {
        return "index8btc_rebase_value";
    }

    public static String getBTCX() {
        return "indexbtci_rebase_value";
    }

    public static String get8BTCVIIndexRebaseValueKey() {
        return "index8btcvi_rebase_value";
    }

    public static String getWeixinRankingKey() {
        return "weixin_ranking";
    }

    public static String getIndexTickKey(String cid, String period) {
        return String.format("index_coin_ticket_%s_%s", cid, period);
    }

    public static String getCoinLastBigTransferTime(String cid) {
        return "coin_lastbigtransfertime" + cid;
    }

    public static String get24HighPriceKey() {
        return String.format("coin_24Highprice");
    }

    public static String get24LowPriceKey() {
        return String.format("coin_24Lowprice");
    }

    //24小时振幅
    public static String get24AmplitudeKey() {
        return String.format("coin_24Amplitude");
    }

    //===== 资讯
    public static String getPrefixViewCountKey(Long newsId) {
        return KEY_PREFIX_VIEW_COUNT + newsId;
    }

    //===== 金币任务
    public static String getGoldTaskSignKey(Long uid) {
        return "gold_sign_" + uid;
    }

    public static String getGoldDayTaskStatusKey(Long uid) {
        return "gold_day_task_" + uid;
    }

    public static String getGoldDayScratchKey(Long uid) {
        return "gold_day_scratch_" + uid;
    }

    public static String getWarningHisCacheKey(Long uid) {
        return "warning_push_" + uid;
    }

    //===== 通用

    public static String getTickerRateKey() {
        return "ticker_rate";
    }

    //矿机排行
    public static String getWebMillRankKey() {
        return "web_mill_rank_market";
    }

    //破发率
    public static String getExchangeBleakRateKey() {
        return "exchange_bleak_rate";
    }

    //挖矿数据监测
    public static String getDigDataMonitorKey() {
        return "web_dig_data_monitor";
    }

    //全网算力趋势
    public static String getNetCalculateForceKey() {
        return "web_net_calculate_force";
    }

    //算力分布图
    public static String getCalPowerDistributKey() {
        return "web_call_power_Distribut";
    }

    //eth区块奖励
    public static String getEthCoinbaseRewardKey() {
        return "web_eth_coinbase_reward";
    }

    //最新出块
    public static String getRecentlyPieceKey() {
        return "web_recently_piece";
    }

    //钱包排行缓存key
    public static String getWalletRankListKey() {
        return "WALLET_RANKING_LIST";
    }

    //交易所雷达数据
    public static String getExchangeRadar() {
        return "EXCHANGE_RADAE_DATA";
    }

    public static String getExchangeLastNewCoin() {
        return "EXCHANGE_NEW_COIN_";
    }

    public static String getCoinTypeChange() {
        return "COIN_TYPE_CHANGE";
    }

    public static String getIMMsgID() {
        return IM_MESSAGE_ID;
    }
    public static String getSysMsgID() {
        return SYS_MESSAGE_ID;
    }

    public static String getIMUserUUIDList(Long userid) {
        return IM_USER_UUID_LIST + userid;
    }

    public static String getIMUserMessageList(Long userid) {
        return IM_USER_MESSAGE_LIST + userid;
    }

    public static String getImUserTokenChatserverList(Long userid) {
        return IM_USER_TOKEN_CHATSERVER_LIST + userid;
    }

    public static String getImUserInfo(Long userId) {
        return IM_USERINFO + userId;
    }

    public static String get8BTCIndexRebaseSymbolPriceKey() {
        return "index8btc_rebase_symbol_price";
    }

    public static String get8BTCVIIndexRebaseSymbolPriceKey() {
        return "index8btcvi_rebase_symbol_price";
    }

    public static String getBadWordListCache() {
        return "badwordlistcache";
    }

    //推送相关

    public static String getAllPushHsetKey() {
        return "push_hset_all_day_sign";
    }

    public static String getSinglePushHsetKey() {
        return "push_hset_single_day_sign";
    }

    public static String getCoinstableSmp() {
        return "Coinstable_secondary_market_premium_";
    }

    public static String getCoinstableTe() {
        return "Coinstable_tracking_error_";
    }

    public static String getCoinstableOp() {
        return "Coinstable_OffsitePrice_";
    }

    public static String getUSDTPublishNum() {
        return "Coinstable_USDT_publish_num";
    }

    public static String getCoinKeyCorrect() {
        return "COINKEY_CORRECT";
    }

    //hyperloglog

    public static String dauHllKey(String date, String productName, String clientType, String deviceType) {
        return String.format(DAU_FORMAT, date, productName, clientType, deviceType);
    }

    public static String mauHllKey(String yearMonth, String productName, String clientName, String deviceType) {
        return String.format(MAU_FORMAT, yearMonth, productName, clientName, deviceType);
    }

    public static String hauHllKey(String productName, String clientName, String deviceType) {
        return String.format(HAU_FORMAT, productName, clientName, deviceType);
    }

    public static String duvHllKey(String provideDate, String productName) {
        return String.format(DUV_FORMAT, provideDate, productName);
    }

    public static String muvHllKey(String provideMonth, String productName) {
        return String.format(MUV_FORMAT, provideMonth, productName);
    }

    public static String huvHllKey(String productName) {
        return String.format(HUV_FORMAT, productName);
    }

    public static String getFutureWord() {
        return "data_centre_future_word";
    }

    public static String getSmsVerifyCodeKey(String mobile) {
        return String.format("sms_login_%s", mobile);
    }

    public static String getEmailVerifyCodeKey(String email) {
        return String.format("email_verify_%s", email);
    }

    public static String getUserKey() {
        return "USER";
    }

    public static String getUserChildKey(String uid) {
        return String.format("userinfo_%s", uid);
    }

    public static String getAhrParam() {
        return "ahr_param";
    }

    public static String getPlateFinance() {
        return "plate_finance";
    }

    public static String getManagerSmsCodeKey(String mobile) {
        return String.format("manager_sms_%s", mobile);
    }

    public static String selfArticle() {
        return "self_article";
    }

    public static String bsvHalfTime() {
        return "bsv_half_time";
    }

    public static String getAgeDistributionKey(){return "age_distribution";};

    public static String getHomeFutureData(){return "home_future_data";};

    public static String getContractListKey(){
        return "CONTRACT_LIST_%s";
    }

    public static String getContractChartExKey(){
        return "CONTRACT_CHART_EX_%s";
    }

    public static String getContractChartCoinKey(){
        return "CONTRACT_CHART_COIN_%s";
    }

    public static String getDealPupilProportionKey(){
        return "DEAL_PUPIL_PROPORTION_%s";
    }

}
